package v1

import (
	"context"
	"time"
	"xjxtld/internal/dao"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gcron"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/os/gtimer"
	"github.com/gogf/gf/v2/util/gutil"
)

func UpDateTable() { //每晚两点
	var (
		err error
	) //0 0 2 * * *
	_, err = gcron.Add(ctx, "0 0 2 * * *", func(ctx gctx.Ctx) {
		BusAndOrg()
		gutil.Dump("已完成更新")
	}, "resh org")
	if err != nil {
		panic(err)
	}
}

func UpDatePB() { //1分钟更新一次排班
	var (
		ctx      = gctx.New()
		interval = time.Second
	)
	gtimer.AddSingleton(ctx, interval*300, func(ctx context.Context) {
		//gutil.Dump(gtime.Now().Timestamp())
		UpDateXjxt()
	})
	select {}
}

// UpdateSanitize 每5分钟更新当天排班数据到fa_sanitize表
func UpdateSanitize() {
	var (
		ctx      = gctx.New()
		interval = time.Second
	)
	gtimer.AddSingleton(ctx, interval*10, func(ctx context.Context) {
		// 获取当天日期
		today := gtime.Now().Format("Y-m-d")

		// 调用更新函数
		err := UpdateXjtcpToSanitize(ctx, today)
		if err != nil {
			gutil.Dump("更新排班数据到fa_sanitize失败:", err)
			return
		}

		gutil.Dump("成功更新排班数据到fa_sanitize表")
	})
	select {}
}

// UpdateXjtcpToSanitize 将fa_xjtcp表的数据更新到fa_sanitize表
// 参数: ctx - 上下文, date - 日期字符串，格式为"Y-m-d"
// 返回: error - 错误信息
func UpdateXjtcpToSanitize(ctx context.Context, date string) error {
	// 定义需要更新的线路白名单
	allowedRoutes := map[string]bool{
		"351路": true, "398路": true, "399路": true, "687路": true,
		"900路": true, "926路": true, "930路": true, "932路": true,
		"935路": true, "980路": true, "986路": true, "991路": true,
		"993路": true, "994路": true, "996路": true, "997路": true,
		"998路": true, "999路": true, "G991路": true, "G993路": true,
		"K929路": true, "T91路": true, "T92路": true, "T01A": true,
		"T01B": true, "218路": true, "K28路": true, "K981路": true,
		"K995路": true, "T01B火炬线": true,
	}

	// 1. 查询当天的排班数据
	var xjtcpList []struct {
		Id             string `json:"id"              orm:"id"`
		PlanArriveTime string `json:"plan_arrive_time" orm:"plan_arrive_time"`
		BusId          string `json:"bus_id"          orm:"bus_id"`
		MainBusSelfNo  string `json:"main_bus_self_no" orm:"main_bus_self_no"`
		StaffWorknum   string `json:"staff_worknum"   orm:"staff_worknum"`
		EmpId          string `json:"emp_id"          orm:"emp_id"`
		StaffName      string `json:"staff_name"      orm:"staff_name"`
		EndStationId   string `json:"end_station_id"  orm:"end_station_id"`
		OrgId          string `json:"org_id"          orm:"org_id"`
		RealArriveTime string `json:"real_arrive_time" orm:"real_arrive_time"`
		RouteId        string `json:"route_id"        orm:"route_id"`
		MainRouteName  string `json:"main_route_name" orm:"main_route_name"`
		ExecDate       string `json:"exec_date"       orm:"exec_date"`
		StartStationId string `json:"start_station_id" orm:"start_station_id"`
		StartStopName  string `json:"start_stop_name" orm:"start_stop_name"`
		Remark         string `json:"remark"          orm:"remark"`
		OrgName        string `json:"orgname"         orm:"orgname"`
		PlanStartTime  string `json:"plan_start_time" orm:"plan_start_time"`
	}

	// 使用ORM查询当天排班数据
	err := dao.FaXjtcp.Ctx(ctx).
		Where("exec_date", date).
		Scan(&xjtcpList)

	if err != nil {
		return err
	}

	if len(xjtcpList) == 0 {
		gutil.Dump("当天没有排班数据")
		return nil
	}

	// 2. 收集所有车辆编号，用于后续查询
	var busSelfIds []string
	for _, item := range xjtcpList {
		if item.MainBusSelfNo != "" {
			busSelfIds = append(busSelfIds, item.MainBusSelfNo)
		}
	}

	// 3. 查询车辆对应的组织ID
	type BusOrgInfo struct {
		BusSelfId string `json:"BUSSELFID" orm:"BUSSELFID"`
		OrgId     string `json:"ORGID"     orm:"ORGID"`
	}
	var busOrgList []BusOrgInfo

	if len(busSelfIds) > 0 {
		err = g.DB().Model("fa_mcbusinfogs").
			Fields("BUSSELFID", "ORGID").
			WhereIn("BUSSELFID", busSelfIds).
			Scan(&busOrgList)

		if err != nil {
			gutil.Dump("获取车辆组织信息失败:", err)
			return err
		}
	}

	// 创建车辆编号到组织ID的映射
	busToOrgMap := make(map[string]string)
	var orgIds []string

	for _, bus := range busOrgList {
		if bus.BusSelfId != "" && bus.OrgId != "" {
			busToOrgMap[bus.BusSelfId] = bus.OrgId
			orgIds = append(orgIds, bus.OrgId)
		}
	}

	// 4. 查询组织ID对应的组织名称
	type OrgInfo struct {
		OrgId   string `json:"ORGID"   orm:"ORGID"`
		OrgName string `json:"ORGNAME" orm:"ORGNAME"`
	}
	var orgInfoList []OrgInfo

	if len(orgIds) > 0 {
		err = g.DB().Model("fa_mcorginfogs").
			Fields("ORGID", "ORGNAME").
			WhereIn("ORGID", orgIds).
			Scan(&orgInfoList)

		if err != nil {
			gutil.Dump("获取组织名称信息失败:", err)
			return err
		}
	}

	// 创建组织ID到组织名称的映射
	orgToNameMap := make(map[string]string)

	for _, org := range orgInfoList {
		if org.OrgId != "" {
			orgToNameMap[org.OrgId] = org.OrgName
		}
	}

	// 5. 将数据转换为fa_sanitize表的格式，只处理白名单中的线路
	var sanitizeList []g.Map
	var filteredCount, totalCount int

	for _, item := range xjtcpList {
		totalCount++

		// 检查线路是否在白名单中，如果不在则跳过
		if !allowedRoutes[item.MainRouteName] {
			continue
		}

		filteredCount++

		// 转换时间为时间戳
		var planArriveTimestamp int64
		var realArriveTimestamp int64
		var planStartTimestamp int64

		// 处理计划到达时间
		if item.PlanArriveTime != "" {
			planArriveTime, err := gtime.StrToTime(item.PlanArriveTime)
			if err == nil && planArriveTime != nil {
				planArriveTimestamp = planArriveTime.Timestamp()
			}
		}

		// 处理实际到达时间
		if item.RealArriveTime != "" {
			realArriveTime, err := gtime.StrToTime(item.RealArriveTime)
			if err == nil && realArriveTime != nil {
				realArriveTimestamp = realArriveTime.Timestamp()
			}
		}

		// 处理计划开始时间
		if item.PlanStartTime != "" {
			planStartTime, err := gtime.StrToTime(item.PlanStartTime)
			if err == nil && planStartTime != nil {
				planStartTimestamp = planStartTime.Timestamp()
			}
		}

		// 获取组织信息
		orgId := item.OrgId
		orgName := item.OrgName

		// 从映射中获取正确的组织ID
		if busOrgId, exists := busToOrgMap[item.MainBusSelfNo]; exists {
			orgId = busOrgId

			// 从映射中获取正确的组织名称
			if name, exists := orgToNameMap[busOrgId]; exists {
				orgName = name
			}
		}

		sanitize := g.Map{
			"DISPLANID":       item.Id,
			"ARRIVETIME":      planArriveTimestamp,
			"BUSID":           item.BusId,
			"CARDID":          item.MainBusSelfNo,
			"DRIVERID":        item.StaffWorknum,
			"EMPID":           item.EmpId,
			"EMPNAME":         item.StaffName,
			"ENDSTATIONID":    item.EndStationId,
			"ISACTIVE":        "1",
			"ISSENT":          "0",
			"ORGID":           orgId,
			"ORGNAME":         orgName,
			"REALARRIVETTIME": realArriveTimestamp,
			"ROUTEID":         item.RouteId,
			"ROUTENAME":       item.MainRouteName,
			"RUNDATE":         item.ExecDate,
			"STATIONID":       item.StartStationId,
			"STATIONNAME":     item.StartStopName,
			"remark":          item.Remark,
			"create_time":     gtime.Timestamp(),
			"staff_worknum":   item.StaffWorknum,
			"plan_start_time": planStartTimestamp,
		}
		sanitizeList = append(sanitizeList, sanitize)
	}

	gutil.Dump("总排班数据:", totalCount, "符合线路条件的数据:", filteredCount)

	// 6. 分批处理数据
	if len(sanitizeList) > 0 {
		batchSize := 50 // 每批处理的记录数
		for i := 0; i < len(sanitizeList); i += batchSize {
			end := i + batchSize
			if end > len(sanitizeList) {
				end = len(sanitizeList)
			}
			batch := sanitizeList[i:end]

			// 使用Save方法，会自动根据主键或唯一键进行更新或插入
			_, err = dao.FaSanitize.Ctx(ctx).OmitEmpty().Data(batch).Save()
			if err != nil {
				gutil.Dump("保存批次数据失败:", err, "批次:", i/batchSize+1)
				return err
			}
		}
		gutil.Dump("成功保存所有批次数据，总记录数:", len(sanitizeList))
	} else {
		gutil.Dump("没有符合条件的线路数据需要更新")
	}

	return nil
}
